package com.cskaoyan.service.wx.impl;

import com.alibaba.druid.sql.SQLUtils;
import com.cskaoyan.bean.admin.promotion.vo.GoodsVo;
import com.cskaoyan.bean.pojo.*;
import com.cskaoyan.bean.wx.goods.bo.PageInfoWxBO;
import com.cskaoyan.bean.wx.goods.vo.*;
import com.cskaoyan.mapper.*;
import com.cskaoyan.service.wx.WxGoodsService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.lang.System;
import java.net.IDN;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;

/**
 * @Classname GoodsServiceImpl
 * @Description
 * @Date 2021/8/14 14:02
 * @Author : xujun
 */
@Transactional
@Service
public class WxGoodsServiceImpl implements WxGoodsService {

    @Autowired
    GoodsMapper goodsMapper;

    @Autowired
    CategoryMapper categoryMapper;

    @Autowired
    BrandMapper brandMapper;

    @Autowired
    UserMapper userMapper;

    @Autowired
    CollectMapper collectMapper;

    @Autowired
    GoodsAttributeMapper attributeMapper;

    @Autowired
    IssueMapper issueMapper;

    @Autowired
    GoodsProductMapper productMapper;

    @Autowired
    GoodsSpecificationMapper specificationMapper;

    @Autowired
    CommentMapper commentMapper;

    @Autowired
    FootprintMapper footprintMapper;

    @Autowired
    SearchHistoryMapper searchHistoryMapper;

    @Autowired
    KeywordMapper keywordMapper;

    @Override
    public CountVo count() {

        CountVo vo = new CountVo();

        GoodsExample example = new GoodsExample();
        example.createCriteria().andDeletedEqualTo(false);

        long count = goodsMapper.countByExample(example);

        vo.setGoodsCount(count);

        return vo;
    }

    @Override
    public CategoryVo category(Integer id) {    // 首页进id作pid，二级类目间进做二级类目id

//        // 只有主页进去才正确，点二级类目会有bug
//        // parentCategory
//        Category parentCategory = categoryMapper.selectByPrimaryKey(id);
//        int pid = parentCategory.getId();
//
//        CategoryExample categoryExample = new CategoryExample();
//        categoryExample.createCriteria().andDeletedEqualTo(false);
//        List<Category> categories = categoryMapper.selectByExample(categoryExample);
//
//        // currentCategory
//        // brotherCategory
//        Category currentCategory = null;
//        int cnt = 0;    // 标记位，标记currentCategory是否已赋值
//        List<Category> brotherCategory = new ArrayList<>();
//        for (Category category : categories) {
//            if (cnt == 0 && category.getPid() == pid) {
//                currentCategory = category;
//                cnt = 1;
//            } else if (cnt == 1 && category.getPid() == pid) {
//                brotherCategory.add(category);
//            }
//        }


        // 这个正确，修复了上述bug
        Category currentCategory = categoryMapper.selectByPrimaryKey(id);

        int pid = currentCategory.getPid();
        boolean isParent;
        if (pid == 0) {
            isParent = true;
        } else {
            isParent = false;
        }

        Category parentCategory;
        if (isParent) {
            // 如果是父分类，这里的 parentCategory 就是自己
            parentCategory = currentCategory;
        } else {
            // 如果不是父分类，就获得父分类
            parentCategory = categoryMapper.selectByPrimaryKey(pid);
        }


        // brotherCategory
        CategoryExample categoryExample = new CategoryExample();
        CategoryExample.Criteria categoryCriteria = categoryExample.createCriteria();
        categoryCriteria.andPidEqualTo(parentCategory.getId());
        categoryCriteria.andDeletedEqualTo(false);
        List<Category> brotherCategory = categoryMapper.selectByExample(categoryExample);


        currentCategory = brotherCategory.get(0);

        // vo
        CategoryVo vo = new CategoryVo();
        vo.setCurrentCategory(currentCategory);
        vo.setParentCategory(parentCategory);
        vo.setBrotherCategory(brotherCategory);

        return vo;
    }

    @Override
    public GoodsRelatedVo related(Integer id) {

        // 获得该商品的类目id
        Goods originalGoods = goodsMapper.selectByPrimaryKey(id);
        Integer categoryId = originalGoods.getCategoryId();

        // 获得相同类目id的商品，最多6个，且其中不能包括自己
        GoodsExample example = new GoodsExample();
        example.createCriteria().andCategoryIdEqualTo(categoryId).andIdNotEqualTo(id).andDeletedEqualTo(false);
        List<Goods> oldGoodsList = goodsMapper.selectByExampleWithBLOBs(example);
        List<Goods> newGoodsList = new ArrayList<>();
        if (oldGoodsList.size() <= 6) {
            newGoodsList = oldGoodsList;
        } else {
            // 我觉得每次显示相似的6个商品应该不一定相同，所以我选择随机显示相似的6个商品
            // 生成不重复的随机6个数字，且每个数字不超过总共相似商品的总数
            Random random = new Random();
            ArrayList<Integer> integers = new ArrayList<>();
            while (true) {
                int index = random.nextInt(oldGoodsList.size());
                if (integers == null) integers.add(index);
                else if (integers.size() < 6) {
                    if (!integers.contains(index)) integers.add(index);
                    else continue;
                } else break;
            }
            // 从数据库中获得对应的6个商品
            for (int i = 0; i < integers.size(); i++) {
                newGoodsList.add(oldGoodsList.get(integers.get(i)));
            }
        }

        // goodsList，封装
        List<GoodsRelatedVo.GoodsRelatedVoInnerVo> goodsList = new ArrayList<>();
        for (Goods goods : newGoodsList) {

            GoodsRelatedVo.GoodsRelatedVoInnerVo goodsRelatedVoInnerVo = new GoodsRelatedVo.GoodsRelatedVoInnerVo();
            BeanUtils.copyProperties(goods, goodsRelatedVoInnerVo);

            goodsList.add(goodsRelatedVoInnerVo);
        }


        GoodsRelatedVo vo = new GoodsRelatedVo();
        vo.setGoodsList(goodsList);

        return vo;
    }


    @Override
    public GoodsDetailVo detail(Integer id) {

        // info
        Goods goods = goodsMapper.selectByPrimaryKey(id);


        // attribute
        GoodsAttributeExample attributeExample = new GoodsAttributeExample();
        attributeExample.createCriteria().andGoodsIdEqualTo(id).andDeletedEqualTo(false);
        List<GoodsAttribute> goodsAttributes = attributeMapper.selectByExample(attributeExample);


        // issue;
        IssueExample issueExample = new IssueExample();
        issueExample.createCriteria().andDeletedEqualTo(false);
        List<Issue> issues = issueMapper.selectByExample(issueExample);


        // productList;
        GoodsProductExample productExample = new GoodsProductExample();
        productExample.createCriteria().andGoodsIdEqualTo(id).andDeletedEqualTo(false);
        List<GoodsProduct> goodsProducts = productMapper.selectByExample(productExample);


        // brand
        Integer brandId = goods.getBrandId();
        Brand brand = brandMapper.selectByPrimaryKey(brandId);

        // groupon
        List<Groupon> groupon = null;


        // userHasCollect
        // 用户浏览商品后，应添加浏览足迹
        // 先获取用户
        String username = (String) SecurityUtils.getSubject().getPrincipal();
//        String username = "test1";

        Integer userHasCollect = 0;  // 是否收藏
        if (username == null) { // 说明未登录
            userHasCollect = 0;
        } else {                // 已登录
            UserExample userExample = new UserExample();
            userExample.createCriteria().andUsernameEqualTo(username);
            List<User> users = userMapper.selectByExample(userExample);
            User user = users.get(0);
            Integer userId = user.getId();
            // 添加足迹
            FootprintExample footprintExample = new FootprintExample();
            footprintExample.createCriteria()
                    .andUserIdEqualTo(userId)
                    .andGoodsIdEqualTo(goods.getId())
                    .andDeletedEqualTo(false);
            List<Footprint> footprints = footprintMapper.selectByExample(footprintExample);

            Date date = new Date(System.currentTimeMillis());
            if (footprints == null) { // 用户之前没浏览过
                Footprint footprint = new Footprint(null, userId, goods.getId(),
                        date, date, false);
                footprintMapper.insertSelective(footprint);
            } else { // 用户之前浏览过，更新时间

                FootprintExample footprintExample1 = new FootprintExample();
                footprintExample1.createCriteria()
                        .andGoodsIdEqualTo(goods.getId())
                        .andUserIdEqualTo(userId)
                        .andDeletedEqualTo(false);

                Footprint footprint = new Footprint();
                footprint.setUpdateTime(date);

                footprintMapper.updateByExampleSelective(footprint, footprintExample1);
            }


            // 再查表该用户是否收藏该商品
            CollectExample collectExample = new CollectExample();
            collectExample.createCriteria()
                    .andTypeEqualTo((byte) 0)
                    .andUserIdEqualTo(userId)
                    .andValueIdEqualTo(id)
                    .andDeletedEqualTo(false);
            List<Collect> collects = collectMapper.selectByExample(collectExample);
            // 查出来没有就说明没收藏，有就是收藏了

            if (collects != null) {
                userHasCollect = 1;
            }

        }


        // specificationList
        GoodsSpecificationExample specificationExample = new GoodsSpecificationExample();
        specificationExample.createCriteria().andGoodsIdEqualTo(id);
        List<GoodsSpecification> specifications = specificationMapper.selectByExample(specificationExample);

        List<GoodsDetailVo.GoodsSpecificationVo.ValueInnerVo> valueList = new ArrayList<>();
        List<GoodsDetailVo.GoodsSpecificationVo> specificationList = new ArrayList<>();

        for (GoodsSpecification goodsSpecification : specifications) {
            // 先封装valueList
            GoodsDetailVo.GoodsSpecificationVo.ValueInnerVo valueInnerVo = new GoodsDetailVo.GoodsSpecificationVo.ValueInnerVo();
            BeanUtils.copyProperties(goodsSpecification, valueInnerVo);
            valueList.add(valueInnerVo);

            // 再封装specificationList
            GoodsDetailVo.GoodsSpecificationVo goodsSpecificationVo = new GoodsDetailVo.GoodsSpecificationVo();
            String name = valueInnerVo.getSpecification();
            goodsSpecificationVo.setName(name);
            goodsSpecificationVo.setValueList(valueList);
            specificationList.add(goodsSpecificationVo);
        }


        // comment，只显示2个，但count显示总个数
        GoodsDetailVo.CommentVo comment = new GoodsDetailVo.CommentVo();
        List<GoodsDetailVo.CommentVo.CommentInnerVo> data = new ArrayList<>();

        CommentExample commentExample = new CommentExample();
        commentExample.createCriteria()
                .andValueIdEqualTo(id)
                .andTypeEqualTo((byte) 0)
                .andDeletedEqualTo(false);
        long count = commentMapper.countByExample(commentExample);

        comment.setCount(count);

        commentExample.setOrderByClause("id limit 2");
        List<Comment> comments = commentMapper.selectByExample(commentExample);
        for (Comment goodsComment : comments) {

            User commentUser = userMapper.selectByPrimaryKey(goodsComment.getUserId());
            String nickname = commentUser.getNickname();
            String avatar = commentUser.getAvatar();

            GoodsDetailVo.CommentVo.CommentInnerVo commentInnerVo = new GoodsDetailVo.CommentVo.CommentInnerVo();
            commentInnerVo.setAddTime(goodsComment.getAddTime());
            commentInnerVo.setAvatar(avatar);
            commentInnerVo.setNickname(nickname);
            commentInnerVo.setContent(goodsComment.getContent());
            commentInnerVo.setId(goodsComment.getId());
            commentInnerVo.setPicList(goodsComment.getPicUrls());

            data.add(commentInnerVo);
        }

        comment.setData(data);


        // 封装返回vo
        GoodsDetailVo vo = new GoodsDetailVo();
        vo.setInfo(goods);
        vo.setBrand(brand);
        vo.setGroupon(groupon);
        vo.setShareImage("");
        vo.setUserHasCollect(userHasCollect);
        vo.setAttribute(goodsAttributes);
        vo.setIssue(issues);
        vo.setProductList(goodsProducts);
        vo.setSpecificationList(specificationList);
        vo.setComment(comment);

        return vo;
    }


    @Override
    public ListVo getGoodsList(PageInfoWxBO bo) {

        PageHelper.startPage(bo.getPage(), bo.getSize());

        ListVo vo = new ListVo();

        // goodsList
        List<GoodsVo> goodsList = goodsMapper.selectWxGoodsList(bo);
        vo.setGoodsList(goodsList);

        // count
        PageInfo<GoodsVo> pageInfo = new PageInfo<>(goodsList);
        long total = pageInfo.getTotal();
        vo.setCount((int) total);

        // filterCategoryList
        if (bo.getIsHot() != null || bo.getIsNew() != null) {

            List<Integer> categoryList = goodsMapper.selectCategoryListInCondition(bo);

            List<Category> filterCategoryList = categoryMapper.selectFilterCategoryList(categoryList);
            vo.setFilterCategoryList(filterCategoryList);

        }

        return vo;
    }


    @Override
    public ListVo searchGoodsList(PageInfoWxBO bo, String keyword) {

        PageHelper.startPage(bo.getPage(), bo.getSize());

        // 先查商品
        List<GoodsVo> goodsList = goodsMapper.searhcGoodsList(bo, keyword);

        // 商品个数
        PageInfo<GoodsVo> pageInfo = new PageInfo<>(goodsList);
        long total = pageInfo.getTotal();

        // 用商品id查出categoryList
        ArrayList idList = new ArrayList();
        for (GoodsVo goodsListVO : goodsList) {
            int id = goodsListVO.getCategoryId();
            if (!idList.contains(id)) {
                idList.add(id); // 商品id的list
            }
        }

        List<Category> filterCategoryLists = goodsMapper.searchCategoryList(idList);

        Date date = new Date(System.currentTimeMillis());
        // 在keyword表中插入或更新keyword的热度
        KeywordExample keywordExample = new KeywordExample();
        keywordExample.createCriteria().andDeletedEqualTo(false).andKeywordEqualTo(keyword);
        List<Keyword> keywords = keywordMapper.selectByExample(keywordExample);
        Keyword keywordRecord = keywords.get(0);
        if (keywordRecord == null) {    // 没该关键字记录，插入
            Keyword newKeyword = new Keyword();
            newKeyword.setAddTime(date);
            newKeyword.setUpdateTime(date);
            newKeyword.setDeleted(false);
            newKeyword.setKeyword(keyword);
            newKeyword.setIsHot(1);
            keywordMapper.insertSelective(newKeyword);
        } else {    // 有该关键字记录，更新
            KeywordExample example = new KeywordExample();
            example.createCriteria().andIdEqualTo(keywordRecord.getId());

            Keyword newKeyword = new Keyword();
            newKeyword.setUpdateTime(date);

            keywordMapper.updateByExampleSelective(newKeyword, example);
        }
        // 如果用户登录,将用户的搜索历史加到表中
        String username = (String) SecurityUtils.getSubject().getPrincipal();
        if (username != null) {
            User user = userMapper.selectByUsername(username);

            SearchHistoryExample searchHistoryExample = new SearchHistoryExample();
            searchHistoryExample.createCriteria()
                    .andUserIdEqualTo(user.getId())
                    .andKeywordEqualTo(keyword)
                    .andDeletedEqualTo(false);

            // 某用户搜索某商品的记录应该只有0条或1条
            List<SearchHistory> searchHistories = searchHistoryMapper.selectByExample(searchHistoryExample);
            SearchHistory history = searchHistories.get(0);

            if (history == null) { // 没有搜索记录就插入记录
                SearchHistory searchHistory = new SearchHistory(null, user.getId(), keyword,
                        "hhh", date, date, false);
                searchHistoryMapper.insertSelective(searchHistory);
            } else { // 有搜索记录就更新搜索时间
                SearchHistoryExample example = new SearchHistoryExample();
                example.createCriteria().andIdEqualTo(history.getId());

                SearchHistory searchHistory = new SearchHistory();
                searchHistory.setUpdateTime(date);

                searchHistoryMapper.updateByExampleSelective(searchHistory, example);
            }
        }

        // 封装vo返回
        ListVo vo = new ListVo();
        vo.setGoodsList(goodsList);
        vo.setCount((int) total);
        vo.setFilterCategoryList(filterCategoryLists);

        return vo;
    }


}
